package com.xukang.batch.processor;

import com.xukang.batch.po.Users;
import com.xukang.batch.service.UserService;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamReader;

import javax.annotation.Resource;
import java.util.List;


/**
 * 通过实现ItemStreamReader跟踪读取位置，Spring Batch 会自动恢复状态, 读取位置应当保存到 数据库中
 */
public class MyItemReader1 implements ItemStreamReader<Users> {

    private ThreadLocal<Integer> threadLocalInt = ThreadLocal.withInitial(() -> 0);
    private List<Users> data; // 数据源

    @Resource
    private UserService userService;

    @Override
    public Users read() {
        System.out.println("read");
        System.out.println("currentThread" + Thread.currentThread().getId());
        Integer currentIndex = threadLocalInt.get();

        if (currentIndex < data.size()) {
            Users user = data.get(currentIndex);
            threadLocalInt.set(currentIndex + 1);
            return user;
        }
        return null; // 读完所有数据
    }

    @Override
    public void open(ExecutionContext executionContext) throws ItemStreamException {
        System.out.println("open");
        System.out.println("currentThread" + Thread.currentThread().getId());

        System.out.println("executionContext(空的):" + executionContext);

        System.out.println("首次执行,加载全量数据");
        threadLocalInt.set(0); // 首次执行
        this.data = loadData(); // 加载全量数据

    }

    @Override
    public void update(ExecutionContext executionContext) throws ItemStreamException {
        // 会在 open后以及write 后执行update
        System.out.println("update");
        System.out.println("currentThread:" + Thread.currentThread().getId());

        // ExecutionContext 持久化,保存当前读取位置
        Integer currentIndex = threadLocalInt.get();
        executionContext.putInt("currentIndex", currentIndex);
        System.out.println("executionContext: " + executionContext);
    }

    @Override
    public void close() throws ItemStreamException {
        // 释放资源
    }

    private List<Users> loadData() {
        System.out.println("loadData");
        // 从数据库/文件加载数据
        return userService.findAll();
    }
}
